import os
import random
import argparse
from datetime import datetime
from moviepy.editor import *

def is_empty_directory(directory_path):
    if not os.path.exists(directory_path):
        raise FileNotFoundError(f"目录不存在：{directory_path}")

    if not os.path.isdir(directory_path):
        raise ValueError(f"给定的路径不是目录：{directory_path}")

    return len(os.listdir(directory_path)) == 0

# 解析命令行参数
parser = argparse.ArgumentParser(description="从指定目录中随机挑选片段，组合成指定长度的视频片段。")
parser.add_argument("-iv", "--video_path", type=str, default="clips_video", help="视频文件路径，默认为空。")
parser.add_argument("-ia", "--audio_path", type=str, default="clips_audio", help="音频文件路径，默认为空。")
parser.add_argument("-o", "--output_path", type=str, default="output", help="输出文件路径，默认为空。")
parser.add_argument("-t", "--target_duration", type=int, default=15, help="目标视频片段长度（秒），默认为15秒。")
parser.add_argument("-vw", "--width", type=int, default=1280, help="输出视频宽度，默认为1280像素。")
parser.add_argument("-vh", "--height", type=int, default=720, help="输出视频高度，默认为720像素。")
parser.add_argument("-qv", "--quality", type=int, default=3, help="视频质量，默认为3。")
args = parser.parse_args()

# 替换以下占位符为实际文件夹路径
input_directory = args.video_path
input_audio_directory = args.audio_path
output_directory = args.output_path

# 确保文件夹路径有效
if not os.path.exists(input_directory):
    raise FileNotFoundError(f"视频文件夹不存在：{input_directory}")

if is_empty_directory(input_directory):
    raise ValueError(f"视频文件夹为空：{input_directory}")

if not os.path.exists(input_audio_directory):
    raise FileNotFoundError(f"音频文件夹不存在：{input_audio_directory}")

if is_empty_directory(input_audio_directory):
    raise ValueError(f"音频文件夹为空：{input_audio_directory}")

if not os.path.exists(output_directory):
    os.makedirs(output_directory)



# ----------------------合成音频----------------------------------------------------
audio_files = [f for f in os.listdir(input_audio_directory) if f.endswith(('.mp4','.mp3', '.wav'))]

# 挑选出能满足长度的音频，组合起来
selected_audio_clips = []
# 随机挑选出来的音频长度
total_audio_duration = 0

final_audio_clip = None
while total_audio_duration< args.target_duration:
    audio_file = random.choice(audio_files)
    audio_path = os.path.join(input_audio_directory, audio_file)
    audio_clip = AudioFileClip(audio_path)

    tmp_total_audio_duration = total_audio_duration + audio_clip.duration
    if tmp_total_audio_duration <= args.target_duration:
        selected_audio_clips.append(audio_clip)
        total_audio_duration += audio_clip.duration
    else:
        #超出部分直接裁剪
        rest_duration = args.target_duration-total_audio_duration
        tmp_audio_clip = audio_clip.subclip(0, rest_duration)
        selected_audio_clips.append(tmp_audio_clip)
        total_audio_duration += tmp_audio_clip.duration
        break

# 将随机挑选的音频片段组合成一个指定长度的音频片段
for audio_clip in selected_audio_clips:
    if final_audio_clip is None:
        final_audio_clip = audio_clip
    else:
        final_audio_clip = concatenate_audioclips([final_audio_clip, audio_clip])

# 如果总长度不足目标长度，从最后一个片段中提取剩余的长度
if total_audio_duration< args.target_duration and len(selected_audio_clips) > 0:
    last_audio_clip = selected_audio_clips[-1]

    missing_duration = args.target_duration - total_audio_duration
    last_audio_clip = last_audio_clip.subclip(0, min(missing_duration, last_audio_clip.duration))
    final_audio_clip = concatenate_audioclips([final_audio_clip, last_audio_clip])

print("总片段时长",final_audio_clip.duration)
# ----------------------合成视频----------------------------------------------------
# 从目录中随机挑选出几个片段，直到总长度达到目标长度
# 获取目录中的所有视频文件
video_files = [f for f in os.listdir(input_directory) if f.endswith(('.mp4', '.avi', '.mkv'))]

selected_video_files = []
total_duration = 0
while total_duration< args.target_duration:
    video_file = random.choice(video_files)
    video_path = os.path.join(input_directory, video_file)
    video_clip = VideoFileClip(video_path)

    if total_duration + video_clip.duration <= args.target_duration:
        selected_video_files.append(video_file)
        total_duration += video_clip.duration
    else:
        break

# 将随机挑选的片段组合成一个指定长度的视频片段
final_clip = None
for video_file in selected_video_files:
    video_path = os.path.join(input_directory, video_file)
    video_clip = VideoFileClip(video_path)

    if final_clip is None:
        final_clip = video_clip
    else:
        final_clip = concatenate_videoclips([final_clip, video_clip])

# 如果总长度不足目标长度，从最后一个片段中提取剩余的长度
if total_duration< args.target_duration:
    last_video_file = selected_video_files[-1]
    last_video_path = os.path.join(input_directory, last_video_file)
    last_video_clip = VideoFileClip(last_video_path)

    missing_duration = args.target_duration - total_duration
    last_video_clip = last_video_clip.subclip(0, min(missing_duration, last_video_clip.duration))
    final_clip = concatenate_videoclips([final_clip, last_video_clip])

# 将音频片段添加到视频片段中
final_clip = final_clip.set_audio(final_audio_clip)
# 调整视频宽度和高度
final_clip = final_clip.resize((args.width, args.height))



# 设置preset值以控制编码速度和压缩效果
preset_values=["ultrafast","superfast","veryfast","faster","fast","medium","slow","slower","veryslow"]
preset_index=args.quality
if preset_index<0 or preset_index>=len(preset_values):
    preset_index=len(preset_values)-1
preset_value=preset_values[preset_index]
print("视频质量：",preset_value)

# 保存组合后的视频片段到指定目录
current_time = datetime.now().strftime("%Y%m%d%H%M%S")
output_filename = f"{current_time}_{args.target_duration}s_{preset_value}_{args.width}x{args.height}.mp4"
output_path = os.path.join(output_directory, output_filename)


# 保存组合后的视频片段到指定目录
final_clip.write_videofile(output_path, codec='libx264',preset=preset_value)

print("已生成组合视频：",output_filename)